import socket, threading, resources

class SocketWriter(threading.Thread):
  def __init__(self, sock, readPipe):
    threading.Thread.__init__(self)
    self._socket = sock
    self._readPipe = readPipe

  def run(self):
    try:
      while TelnetServer.run:
        try:
          self._socket.send(self._readPipe(1))
        except socket.timeout:
          pass
    except socket.error:
      pass

class SocketReader(threading.Thread):
  def __init__(self, sock, writePipe):
    threading.Thread.__init__(self)
    self._socket = sock
    self._writePipe = writePipe

  def run(self):
    try:
      while TelnetServer.run:
        try:
          ch = self._socket.recv(1)
          if ch == b'\xff':
            command = self._socket.recv(1)
            choice = self._socket.recv(1)
            match command:
              case b'\xfb':
                if choice == b'\x03':
                  self._socket.send(b'\xff\xfd' + choice)
                else:
                  self._socket.send(b'\xff\xfe' + choice)
              case b'\xfc':
                self._socket.send(b'\xff\xfe' + choice)
              case b'\xfd':
                if choice == b'\x03' or choice == b'\x01':
                  self._socket.send(b'\xff\xfb' + choice)
                else:
                  self._socket.send(b'\xff\xfc' + choice)
              case b'\xfe':
                self._socket.send(b'\xff\xfc' + choice)
          else:
            self._writePipe(ch)
        except socket.timeout:
          pass
    except socket.error:
      pass

class TelnetHandler(threading.Thread):
  def __init__(self, sock, readPipe, writePipe):
    threading.Thread.__init__(self)
    self._socket = sock
    self._readPipe = readPipe
    self._writePipe = writePipe
  
  def run(self):
    self._socket.send(b'\xff\xf9\xff\xfd\x2d')
    self._socket.recv(3)
    reader = SocketReader(self._socket, self._writePipe)
    writer = SocketWriter(self._socket, self._readPipe)
    reader.start()
    writer.start()
    reader.join()
    writer.join()
    self._socket.close()

class TelnetServer(object):
  run = True
  telnetHandlers = []

  def __init__(self, readPipe, writePipe, ip = '127.0.0.1', port = 23, timeout = 0.01):
    self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self._socket.settimeout(timeout)
    self._readPipe = readPipe
    self._writePipe = writePipe
    self._socket.bind((ip, port))
    self._socket.listen(20)
  
  def start(self):
    while TelnetServer.run:
      try:
        sock, _ = self._socket.accept()
        sock.settimeout(0.1)
        handler = TelnetHandler(sock, self._readPipe, self._writePipe)
        TelnetServer.telnetHandlers.append(handler)
        handler.start()
      except socket.timeout:
        pass
    print(resources.resource(resources.Resource.SERVER_STOP, resources.Language.CHINESE))
    for handler in TelnetServer.telnetHandlers:
      if handler.is_alive():
        handler.join()
    self._socket.close()
